﻿using System;
using System.Collections.Generic;
using System.Text;

namespace POSPlus.MvcPassiveView
{
	/// <summary>
	/// Keeps track of all the events for the information transfer from model to view.
	/// </summary>
	public class ChangeRequestEvents
	{
		#region Members
		private Dictionary<Type, Dictionary<String, Object>> _pool;
		private Object _sender;
		#endregion

		#region Constructors
		public ChangeRequestEvents(Object sender)
		{
			_pool = new Dictionary<Type, Dictionary<String, Object>>();
			_sender = sender;
		}
		#endregion

		#region Methods
		public void RegisterListener<T>(String propertyName, EventHandler<PropertyChangeRequestEventArgs<T>> handler)
		{
			Type t = typeof(T);

			if (!_pool.ContainsKey(t))
				_pool.Add(t, new Dictionary<String, Object>());

			Dictionary<String, Object> events = _pool[t];

			if (!events.ContainsKey(propertyName))
				events.Add(propertyName, new EventHolder<T>());

			EventHolder<T> holder = events[propertyName] as EventHolder<T>;

			holder.OnEvent += handler;
		}

		public void UnRegisterListener<T>(String propertyName, EventHandler<PropertyChangeRequestEventArgs<T>> handler)
		{
			Type t = typeof(T);

			if (_pool.ContainsKey(t))
				return;

			Dictionary<String, Object> events = _pool[t];

			if (!events.ContainsKey(propertyName))
				return;

			EventHolder<T> holder = events[propertyName] as EventHolder<T>;

			holder.OnEvent -= handler;
		}

		public void Fire<T>(String propertyName, T requestedValue)
		{
			Type t = typeof(T);

			if (!_pool.ContainsKey(t))
				return;

			Dictionary<String, Object> events = _pool[t];

			if (!events.ContainsKey(propertyName))
				return;

			EventHolder<T> holder = events[propertyName] as EventHolder<T>;

			holder.Fire(_sender, requestedValue);
		}
		#endregion

		#region Classes
		private class EventHolder<T>
		{
			private event EventHandler<PropertyChangeRequestEventArgs<T>> _onEvent;

			public void Fire(Object sender, T requestedValue)
			{
				if (null != _onEvent)
					_onEvent(sender, new PropertyChangeRequestEventArgs<T>(requestedValue));
			}

			public event EventHandler<PropertyChangeRequestEventArgs<T>> OnEvent
			{
				add { _onEvent += value; }
				remove { _onEvent -= value; }
			}
		}
		#endregion
	}
}
